package com.tuling.elasticsearch.controller;

import co.elastic.clients.elasticsearch._types.query_dsl.IdsQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryStringQuery;
import com.tuling.dal.dao.PmsProductDao;
import com.tuling.dal.entity.PmsProduct;
import com.tuling.elasticsearch.convert.ProductConvert;
import com.tuling.elasticsearch.entity.Product;
import com.tuling.elasticsearch.entity.Users;
import io.lettuce.core.ScriptOutputType;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.DocumentOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.redis.repository.support.QueryByExampleRedisExecutor;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
public class ProductController {
    @Autowired
    private ElasticsearchOperations elasticsearchOperations;



    @Resource
    private PmsProductDao pmsProductDao;
    @PostMapping("/product")
    public Long save(@RequestBody Product person) {
        Product savedEntity = elasticsearchOperations.save(person);
        return savedEntity.getId();
    }

    @GetMapping("/product/{id}")
    public Product findById(@PathVariable("id")  Long id) {
        Product product = elasticsearchOperations.get(id.toString(), Product.class);
        return product;
    }
    @PostMapping("/updateProduct")
    public UpdateResponse updateProduct(@RequestBody Product product) {
        System.out.println("xxxxxxxxxxx");
        UpdateResponse update = elasticsearchOperations.update(product);
        System.out.println("xxxxxxxxxxx");
        return update;
    }
    @PutMapping("/updateByQuery")
    public ByQueryResponse updateByQuery(@RequestBody UpdateQuery updateQuery) {
        System.out.println("xxxxxxxxxxx");
        IndexCoordinates index = IndexCoordinates.of("product");
        ByQueryResponse byQueryResponse = elasticsearchOperations.updateByQuery(updateQuery, index);
        System.out.println("xxxxxxxxxxx");
        return byQueryResponse;
    }


    @Autowired
    private ProductConvert productConvert;
    @GetMapping("/importAll")
    public void importAll() {
        PageRequest pageRequest = PageRequest.of(1, 20);
        PmsProduct pmsProduct = new PmsProduct();
        List<PmsProduct> pmsProducts = pmsProductDao.queryAllByLimit(pmsProduct, pageRequest);
        System.out.println("mysql 中查询出来的数据为"+pmsProducts.size());
        List<Product> products = productConvert.pmsProducts2Products(pmsProducts);
        //将查询出来的数据存储的ES 中
        Iterable<Product> save = elasticsearchOperations.save(products);
        System.out.println(save);
    }
    @GetMapping("/search")
    public SearchHits<Product> search(String keyword, Integer pageNum, Integer pageSize) {
        //查询所有数据
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        SearchHits<Product> searchResult = elasticsearchOperations.search(Query.findAll(), Product.class);
        return searchResult;
    }
    @GetMapping("/searchByIds")
    public SearchHits<Product> searchByIds() {
        //按照ID 进行查询
        Query query = elasticsearchOperations.idsQuery(List.of("35", "36"));
        SearchHits<Product> searchResult = elasticsearchOperations.search(query, Product.class);
        System.out.println("xxxxxxxxxx");
        return searchResult;
    }

    @GetMapping("/searchCondition")
    public Map<String, Object>  searchCondition() {
        IndexOperations indexOperations = elasticsearchOperations.indexOps(Product.class);
        Map<String, Object> mapping = indexOperations.getMapping();
        System.out.println(indexOperations);
        return mapping;
    }


    @GetMapping("/queryUpdate/{id}")
    public void updateProduct(@PathVariable Long id){
        //根据id 查询修改数据
        UpdateQuery updateQuery = UpdateQuery.builder(String.valueOf(id)).withDocument(Document.from(Map.of("name", "tuling小米 红米5A 全网通版 3GB+32GB 香槟金 移动联通电信4G手机 双卡双待")))
                .build();
        UpdateResponse update = elasticsearchOperations.update(updateQuery, IndexCoordinates.of("products"));
        System.out.println(update);
    }

    @GetMapping("queryString")
    public SearchHits<Product> queryString() {
        //查询字符串数据
        StringQuery query = new StringQuery("{\"match\":{\"productSn\":\"7437789\"}}");
        SearchHits<Product> search = elasticsearchOperations.search(query, Product.class);
        return search;
    }
//    void stringQuery() {
//        String dsl = """
//               {"bool":{"must":[{"match":{"city":"上海"}},{"match":{"sex":"男"}},{"range":{"age":{"gte":40,"lte":60}}}]}}
//            """;
//        Query query = new StringQuery(dsl);
//
//        List<SearchHit<User>> searchHitList = elasticsearchOperations.search(query, User.class).getSearchHits();
//        searchHitList.forEach(searchHit -> System.out.println(JSON.toJSONString(searchHit.getContent(), JSONWriter.Feature.PrettyFormat))
//        );
//    }

    @GetMapping("criteriaQuery")
    public SearchHits<Product> criteriaQuery() {
        //查询字符串数据
        CriteriaQuery productSn = new CriteriaQuery(new Criteria("productSn").is("7437789").or(
                new Criteria("name").is("tuling小米 红米5A 全网通版 3GB+32GB 香槟金 移动联通电信4G手机 双卡双待")
        ));
        SearchHits<Product> search = elasticsearchOperations.search(productSn, Product.class);
        return search;
    }
    @GetMapping("nativeQuery")
    public SearchHits<Product> nativeQuery(){
        NativeQuery productSn = NativeQuery.builder().withQuery(q -> q.match(a -> a.field("productSn").query("7437789"))).build();
        SearchHits<Product> search = elasticsearchOperations.search(productSn, Product.class);
        System.out.println(search);
        return search;
    }



    /**
     * 操作索引和映射
     */
    @GetMapping("/createUsersMapping")
    public void indexOperationsUsersMapping() {
        //创建索引操作
        IndexOperations indexOperations = elasticsearchOperations.indexOps(Users.class);
        //创建索引
        indexOperations.create();
        //创建映射
        boolean bool = indexOperations.putMapping(indexOperations.createMapping());
        System.out.println(bool);
//        删除索引
//        restTemplate.indexOps(Student.class).delete();
    }
}
